<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>贪吃蛇</title>
    <style>
      #cont table {
        border: 1px #ccc solid;
        border-collapse: collapse;
        background-image: url(./timg01.png);
      }
      #cont table td {
        width: 10px;
        height: 10px;
      }

      .she {
        background-color: #31ff2a;
      }

      .shiwu {
        background-color: red;
      }
    </style>
  </head>
  <body>
    地图大小：
    <select name="" id="dt">
      <option value="20">小</option>
      <option value="30">中</option>
      <option value="50">大</option>
    </select>

    移动速度：
    <select name="" id="sd">
      <option value="800">慢</option>
      <option value="500">中</option>
      <option value="200">快</option>
    </select>

    <button onclick="Obj.init()">开始</button>
    <hr />
    <div id="cont"></div>
    <script>
      //待解决bug按键连续输入太快无法监听（定时器执行太慢导致），空格键蛇身边长bug（空格键出发了开始按钮）
      //封装对象
      var Obj = {
        //全局容器（用于存储）
        map: "", //地图对象
        snake: [], //蛇身位置
        food_line: "", //食物行
        food_column: "", //食物列
        is_die: true, //是否玩完了
        h:0,//控制上下方向
        l:1,//控制左右方向
        //封装对象获取节点,参数为节点Id（获取节点对节点进行dom操作）
        $: function (domId) {
          return document.getElementById(domId);
        },
        //地图生成
        create_map: function () {
          this.map = this.$("dt");//获取地图dom节点
          this.map = Number(this.map.value); //绘制地图大小
          //生成对应行和列的地图
          var tab = "<table>";
          for (var i = 1; i <= this.map; i++) {
            tab += "<tr>";
            for (var j = 1; j <= this.map; j++) {
              //给定唯一标示，为了快速的找到它
              tab += '<td id="box_' + i + "_" + j + '"></td>';
            }
            tab += "</tr>";
          }
          tab += "</table>";
          //添加到div里面
          this.$("cont").innerHTML = tab;
        },
        //初始化蛇方法
        snake_location:function () {
        //默认在第三行的第三列开始
        for (var i = 3; i <= 7; i++) {
          this.snake[this.snake.length] = [3, i];
        }
      },
      //画蛇（根据this.snake 里存的行和列的数据去改变 对应的 td 背景--给td加一个class）
      create_snake:function () {
        //清除this.snake里面第一个td对应的class;
        var tds = document.getElementsByTagName("td");
        for (vo in tds) {
          if (tds[vo].className == "she") {
            tds[vo].className = "";
          }
        }
        for (key in this.snake) {
          var td = this.$("box_" + this.snake[key][0] + "_" + this.snake[key][1]);
          td.className = "she";
        }
      },
      //食物 （1.随机生成 2.不能出现在蛇的身上 3.不能超出地图）
      create_food:function () {
        this.food_line = Math.floor(Math.random() * this.map) + 1;
        this.food_column = Math.floor(Math.random() * this.map) + 1;
        //判断是否出现在蛇的身上；
        var is = true;
        for (key in this.snake) {
          if (this.snake[key][0] == this.food_line && this.snake[key][1] == this.food_column) {
            //代表出现在了蛇的身上；
            is = false;
            break;
          }
        }
        if (is) {
          //没有出现在蛇身上
          //改变对应td 的背景
          this.$("box_" + this.food_line + "_" + this.food_column).className = "shiwu"
        } else {
          //出现在了蛇身上；
          this.create_food()
        }
      },
      //移动方法
      snake_move:function () {
        var sd = this.$("sd").value;
        //定义定时器用来移动
        //蛇怎么移动
        //蛇头(this.snake 的最后一个元素)+1,蛇尾(this.snake 的第一个元素)-1;
        dsq = setInterval(function () {
          //改变this.snake 的内容
          console.log(Obj.snake);
          var shet_h = Obj.snake[Obj.snake.length - 1][0];
          var shet_l = Obj.snake[Obj.snake.length - 1][1];

          //根据行 和列 来给定蛇头
          shet_h = shet_h + Obj.h;
          shet_l = shet_l + Obj.l;

          //1.判断是否吃到食物
          if (shet_h != Obj.food_line || shet_l != Obj.food_column) {
            //没有吃到了食物
            //蛇尾减一
            Obj.snake.shift(); //蛇尾减一
          } else {
            //重置食物
            Obj.create_food();
          }
          //2.判断是否撞墙
          if (shet_h <= 0 || shet_h >= Obj.map || shet_l <= 0 || shet_l >= Obj.map) {
            alert("你撞墙了,死了!");
            //停止运动
            clearInterval(dsq);
            return false;
          }
          //3.判断是否吃到自己
          for (key in Obj.snake) {
            if (Obj.snake[key][0] == shet_h && Obj.snake[key][1] == shet_l) {
              alert("你把自己咬死了!");
              //停止运动
              clearInterval(dsq);
              return false;
            }
          }
          //蛇头加一
          Obj.snake[Obj.snake.length] = [shet_h, shet_l];
          //画蛇
          Obj.create_snake();
          Obj.is_die = true;
        }, sd);
      },
      //开始游戏
      init:function () {
        //1.生成地图(表格)
        this.create_map();
        //2.生成蛇
        this.snake_location();
        //3.画蛇
        this.create_snake();
        //4.食物
        this.create_food();
        //5.移动
        this.snake_move();
      }
      }

      document.onkeydown = function (event) {
        if (!Obj.is_die) {
          return false;
        }
        //判断按下的键
        switch (event.keyCode) {
          case 37:
            if (Obj.l != 1) {
              Obj.l = -1;
              Obj.h= 0;
            }
            break;
          case 38:
            if (Obj.h!= 1) {
              Obj.l = 0;
              Obj.h= -1;
            }
            break;
          case 39:
            if (Obj.l != -1) {
              Obj.l = 1;
              Obj.h= 0;
            }
            break;
          case 40:
            if (Obj.h!= -1) {
              Obj.l = 0;
              Obj.h = 1;
            }
            break;
        }
        Obj.is_die = false;
      }
    </script>
  </body>
</html>
